package com.gopay.bis.service.bank.impl.expay;

import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Map;

import javax.annotation.Resource;

import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;

import com.gopay.bis.common.util.BankLogUtils;
import com.gopay.bis.common.util.BisPayCheckUtils;
import com.gopay.bis.common.util.TransUtil;
import com.gopay.bis.common.util.constants.BisPayConstants;
import com.gopay.bis.manager.bank.BankOrderManager;
import com.gopay.bis.manager.bank.expay.YspayAdPayManager;
import com.gopay.bis.service.bank.sms.SmsSupportController;
import com.gopay.common.Result;
import com.gopay.common.constants.bank.YspayAdpayConstants;
import com.gopay.common.constants.proccode.ProcCodeConstants;
import com.gopay.common.domain.bank.BankOrder;
import com.gopay.common.domain.bank.ExPayBaseMessage;
import com.gopay.common.domain.bank.yspay.expay.pay.YspayAdPayMessage;
import com.gopay.common.exception.GopayException;
import com.gopay.remote.bank.AdjustInteractRemoteService;
import com.gopay.remote.bank.ExPayInteractRemoteService;

/**
 * 银盛代扣接口
 *
 * @author wangxintao
 * @YspayAdPayServiceImpl.java
 */
public class YspayAdPayServiceImpl implements ExPayInteractRemoteService, AdjustInteractRemoteService {
    @Resource(name = "yspayAdPayManager")
    private YspayAdPayManager yspayAdPayManager;
    // 短信验证码处理类
    public SmsSupportController smsController;
    @Resource(name = "bankOrderManager")
    private BankOrderManager bankOrderManager;
    private static Logger logger = LoggerFactory.getLogger(YspayAdPayServiceImpl.class);

    /**
     * 代扣请求
     */
    public Result payment(ExPayBaseMessage baseMsg) {
        Result result = new Result(true);
        baseMsg.setBankOrderId("YS" + TransUtil.processOrderIdTo14Digit(baseMsg.getOrderId()));
        YspayAdPayMessage message = new YspayAdPayMessage();
        BeanUtils.copyProperties(baseMsg, message);
        try {
            yspayAdPayManager.sign(message);
            message = (YspayAdPayMessage) yspayAdPayManager.payment(message);
            result.setModel("res", message);
            if (message.getBusiState().equals(YspayAdpayConstants.YSPAY_STATE_SUCCESS)) {
            	// 提交支付请求成功
				result.setModel("flag", true);
                logger.error("yspayadpay result flag:success");
            }  else {
            	// 提交支付请求或验签失败
				result.setModel("flag", false);
				// 记录数据库失败信息 add by zhengxue 20170313
				result.setModel("retMsg", StringUtils.isEmpty(message.getNote()) ? "yspayadpay result flag:fail" : message.getNote());
                logger.error("yspayadpay result flag:fail");
            }
            result.setSuccess(true);
        } catch (GopayException e) {
            BankLogUtils.printServiceImplExceptionLog(e);
            result.setResultCode(e.getErrCode());
        } catch (Exception ex) {
            BankLogUtils.printServiceImplExceptionLog(ex);
            result.setResultCode(ProcCodeConstants.PROC_CODE_100E6057);
        }
        return result;
    }

    /**
     * 订单查询
     */
    public Result queryOrder(ExPayBaseMessage base) {
        Result result = new Result(false);
        YspayAdPayMessage message = new YspayAdPayMessage();
        BeanUtils.copyProperties(base, message);
        try {
            message = (YspayAdPayMessage) yspayAdPayManager.query(message);
            // 判断是否对账单查询
            if (null != message && message.isAdjustFlag()) {
                result.setDefaultModel(message);
                return result;
            }
            result.setSuccess(true);
            result.setDefaultModel(message);
            if (BisPayCheckUtils.checkExternalOrderID(base.getOrderId())) {
                Map<String, String> param = new HashMap<String, String>();
                String amount = base.getAmount().toString();
                param.put("orderId", base.getOrderId());
                param.put("amount", amount);
                if (message == null) {
                    // 查询结果为空
                    param.put("returnCode", BisPayConstants.QUERYSTATE_FAIL);
                    param.put("returnMessage", "银行返回对账结果为空");
                    param.put("tradeState", BisPayConstants.TRADESTATE_OTHER);
                    result.setModel("queryResult", param);
                    return result;
                }
                logger.error("isflag:" + message.isFlag() + ",state:" + message.getState());
                if (message.isFlag()) {
                    //成功处理
                    if (YspayAdpayConstants.YSPAY_STATE_SUCCESS.equals(message
                            .getState())) {
                        logger.error("yspayadpayquery 00");
                        param.put("returnCode", BisPayConstants.QUERYSTATE_SUCCESS);
                        param.put("tradeState", BisPayConstants.TRADESTATE_SUCCESS);
                        param.put("returnMessage", "交易成功");
                    } else if (YspayAdpayConstants.YSPAY_STATE_DEALING
                            .equals(message.getState())
                            ) {
                        logger.error("yspayadpayquery 50");
                        param.put("returnCode", BisPayConstants.QUERYSTATE_SUCCESS);
                        param.put("tradeState", BisPayConstants.TRADESTATE_OTHER);
                        param.put("returnMessage", "银行订单正在处理中");
                    } else {
                        logger.error("yspayadpayquery 99");
                        param.put("returnCode", BisPayConstants.QUERYSTATE_SUCCESS);
                        param.put("tradeState", BisPayConstants.TRADESTATE_FAIL);
                        param.put("returnMessage", "交易失败");
                    }
                } else {
                    param.put("returnCode", BisPayConstants.QUERYSTATE_SUCCESS);
                    param.put("tradeState", BisPayConstants.TRADESTATE_OTHER);
                    param.put("returnMessage", "银行验签失败");
                }
                result.setModel("queryResult", param);
            }
        } catch (GopayException e) {
            BankLogUtils.printServiceImplExceptionLog(e);
            result.setResultCode(e.getErrCode());
        } catch (Exception ex) {
            BankLogUtils.printServiceImplExceptionLog(ex);
            result.setResultCode(ProcCodeConstants.PROC_CODE_100E6058);
        }
        return result;
    }

    /**
     * 实名认证
     */
    public Result certification(ExPayBaseMessage baseMsg) {
        Result result = new Result(false);
        YspayAdPayMessage message = new YspayAdPayMessage();
        BeanUtils.copyProperties(baseMsg, message);
        try {
            message = (YspayAdPayMessage) yspayAdPayManager.certification(message);
            if (YspayAdpayConstants.YSPAY_CERT_SUCCESS.equals(message
                    .getCode()) && YspayAdpayConstants.YSPAY_STATE_SUCCESS.equals(message.getBusiState())) {
                // 代扣接口认证成功
                result.setModel("flag", true);
            } else {
                result.setModel("flag", false);
            }
            result.setModel("retMsg", message.getNote());
            result.setSuccess(true);
        } catch (GopayException e) {
            BankLogUtils.printServiceImplExceptionLog(e);
            result.setResultCode(e.getErrCode());
        } catch (Exception ex) {
            BankLogUtils.printServiceImplExceptionLog(ex);
            result.setResultCode(ProcCodeConstants.PROC_CODE_100E6076);
        }
        return result;
    }

    public Result sendSms(ExPayBaseMessage baseMsg) {
        Result result = new Result(false);
        YspayAdPayMessage message = new YspayAdPayMessage();
        BeanUtils.copyProperties(baseMsg, message);
        try {
            Map<String, String> smsRes = smsController.sendSMS(message);
            if (ProcCodeConstants.PROC_CODE_100E6102.equals(smsRes.get("resCode"))) {
                // 短信发送成功
                result.setModel("flag", true);
            } else {
                // 短信发送失败
                result.setModel("flag", false);
            }
            result.setModel("sendCount", smsRes.get("sendCount"));
            result.setModel("retMsg", smsRes.get("retMsg"));
            result.setModel("resCode", smsRes.get("resCode"));
            result.setResultCode(smsRes.get("resCode"));
            result.setSuccess(true);
        } catch (Exception ex) {
            BankLogUtils.printServiceImplExceptionLog(ex);
            result.setResultCode(ProcCodeConstants.PROC_CODE_100E6077);
        }
        return result;
    }

    public Result checkSms(ExPayBaseMessage baseMsg) {
        Result result = new Result(false);
        YspayAdPayMessage message = new YspayAdPayMessage();
        BeanUtils.copyProperties(baseMsg, message);
        try {
            Map<String, String> smsRes = smsController.checkSMS(message);
            if (ProcCodeConstants.PROC_CODE_100E6091.equals(smsRes.get("resCode"))) {
                // 验证通过
                result.setModel("flag", true);               
            } else {
                // 验证失败
                result.setModel("flag", false);
                if(!ProcCodeConstants.PROC_CODE_100E6099.equals(smsRes.get("resCode"))){
                    Map<String, String> freezeRes = smsController.freezeCard(message);
                    if(freezeRes != null)
                        smsRes = freezeRes;
                }
            }
            result.setModel("failCount", smsRes.get("failCount"));
            result.setModel("retMsg", smsRes.get("retMsg"));
            result.setModel("resCode", smsRes.get("resCode"));
            result.setResultCode(smsRes.get("resCode"));
            result.setSuccess(true);
        } catch (Exception ex) {
            BankLogUtils.printServiceImplExceptionLog(ex);
            result.setResultCode(ProcCodeConstants.PROC_CODE_100E6078);
        }
        return result;
    }

    @Override
    public Result sign(ExPayBaseMessage baseMsg) {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public Result verify(ExPayBaseMessage baseMsg) {
        Result result = new Result(false);
        YspayAdPayMessage message = new YspayAdPayMessage();
        BeanUtils.copyProperties(baseMsg, message);
        try {
            YspayAdPayMessage yspayAdPayMessage = (YspayAdPayMessage) yspayAdPayManager.verify(message);
            BankOrder bankOrder = bankOrderManager.getBankOrderById(yspayAdPayMessage.getBankOrderId());
            yspayAdPayMessage.setOrderId(bankOrder.getOrderId());
            result.setModel("res", yspayAdPayMessage);
            result.setDefaultModel(yspayAdPayMessage.isFlag());
            Map<String, String> param = new HashMap<String, String>();
            if (yspayAdPayMessage.isFlag()
                    && YspayAdpayConstants.YSPAY_STATE_SUCCESS.equals(yspayAdPayMessage.getBusiState())) {
                param.put("orderId", yspayAdPayMessage.getOrderId());
                param.put("amt", yspayAdPayMessage.getOrderAmount());
                param.put("cardType", "Unknown");
                param.put("notifyNum", "1");
                param.put("payStatus", "00");
                param.put("retCode", "00");
                param.put("retMsg", "验签成功");
                param.put("signData", message.getSignMessage());
                param.put("isFront", String.valueOf(baseMsg.isFront()));
                logger.error("通知cashier 金额  yspay--:"+yspayAdPayMessage.getOrderAmount());
                result.setModel("isNotifyCashier", param);
                result.setSuccess(true);
                result.setOrderStatus(true);
            } else {
            	 param.put("orderId", yspayAdPayMessage.getOrderId());
                 param.put("amt", yspayAdPayMessage.getOrderAmount());
                 param.put("cardType", "Unknown");
                 param.put("notifyNum", "1");
                 param.put("payStatus", "01");
                 param.put("retCode", "01");
                 // 记录数据库失败信息 add by zhengxue 20170313
                 param.put("retMsg", StringUtils.isEmpty(yspayAdPayMessage.getNote()) ? "交易失败" : yspayAdPayMessage.getNote());
                 param.put("signData", message.getSignMessage());
                 param.put("isFront", String.valueOf(baseMsg.isFront()));
                 result.setModel("isNotifyCashier", param);
                result.setSuccess(true);
                result.setOrderStatus(false);
            }
        } catch (GopayException e) {
            BankLogUtils.printServiceImplExceptionLog(e);
            result.setResultCode(e.getErrCode());
        } catch (Exception ex) {
            BankLogUtils.printServiceImplExceptionLog(ex);
            result.setResultCode(ProcCodeConstants.PROC_CODE_100E6064);
        }
        return result;
    }

    @Override
    public Result adjust(ExPayBaseMessage baseMsg) {
        Result result = new Result(false);
        YspayAdPayMessage message = new YspayAdPayMessage();
        BeanUtils.copyProperties(baseMsg, message);
        try {
            message = (YspayAdPayMessage) yspayAdPayManager.adjust(message);
        } catch (GopayException e) {
            e.printStackTrace();
        }
        result.setDefaultModel(message);
        return result;
    }

    @Override
    public Result treatyQuery(ExPayBaseMessage baseMsg) {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public Result cancel(ExPayBaseMessage baseMsg) {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public Result refund(ExPayBaseMessage baseMsg) {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public Result queryCvn(ExPayBaseMessage baseMsg) {
        // TODO Auto-generated method stub
        return null;
    }

    protected String formatAmt(String amtStr) {
        amtStr = amtStr.replaceAll("^(0+)", "");

        // 增加校验功能，防止误操作
        if (amtStr.indexOf(".") > -1) {
            return amtStr;
        }

        BigDecimal amt = null;
        try {
            amt = new BigDecimal(amtStr);
        } catch (Exception e) {
            amt = new BigDecimal("0");
        }
        amt = amt.movePointLeft(2);
        return amt.toString();
    }

    public SmsSupportController getSmsController() {
        return smsController;
    }

    public void setSmsController(SmsSupportController smsController) {
        this.smsController = smsController;
    }

    @Override
    public Result queryNeedCert(ExPayBaseMessage baseMsg) {
        // TODO Auto-generated method stub
        return null;
    }
/*	@Override
	public Result refundQuery(ExPayBaseMessage baseMsg) {
		// TODO Auto-generated method stub
		return null;
	}*/

    @Override
    public Result refundBack(ExPayBaseMessage baseMsg) {
        // TODO Auto-generated method stub
        return null;
    }
}
